package stackoverflow.domain.user;

import java.util.Set;

import org.apache.commons.lang.Validate;

import stackoverflow.domain.shared.Entity;
import stackoverflow.domain.shared.IdGenerator;


public class User implements Entity<User>
{
	private String id = IdGenerator.createId();
    private String name;
    private String password;
    private boolean isActive;
    private Set<UserRole> roles;
    
    public enum UserRole {
    	Admin,User,Moderator;
    }
    
	public static class UserBuilder
	{
	    private String name;
	    private String password;
	    private boolean isActive;
	    private Set<UserRole> roles;
		
		private static final String nameMustNotBeNull="Name must not be null";
		private static final String nameMustNotBeEmpty="Name must not be empty";
		private static final String passwordMustNotBeNull="Password must not be null";		
		private static final String passwordMustNotBeEmpty="Password must not be empty";		
		private static final String atLeastOneRoleRequired ="User requires at least one role.";
		
		public UserBuilder()
		{}
		
		public UserBuilder name(String name)
		{ 
			this.name = name; 
			return this; 
		}

		public UserBuilder password(String password)
		{ 
			this.password = password; 
			return this; 
		}

		public UserBuilder activityStatus(boolean activityStatus)
		{ 
			this.isActive = activityStatus; 
			return this; 
		}
		
		public UserBuilder roles(Set<UserRole> roles)
        { 
			this.roles = roles; 
			return this; 
		}
		
		public User build() 
		{
			Validate.notNull(this.name, nameMustNotBeNull);
			Validate.notNull(this.password, passwordMustNotBeNull);
			Validate.notEmpty(this.name, nameMustNotBeEmpty);
			Validate.notEmpty(this.password, passwordMustNotBeEmpty);
			Validate.notEmpty(this.roles, atLeastOneRoleRequired);
			return new User(this);
	    }
	}

    private User(UserBuilder userBuilder)
    {
    	this.name = userBuilder.name;
    	this.password = userBuilder.password;
    	this.isActive = userBuilder.isActive;
    	this.roles = userBuilder.roles;
    }
    
	public String getId()
	{
		return id;
	}
	
	private void setId(String userId) {
		this.id = userId;
	}

	public String getUserName() {
		return name;
	}

	public void setUserName(String userName) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public boolean getIsActive() {
		return isActive;
	}

	public void setActive(boolean isActive) {
		this.isActive = isActive;
	}

	public Set<UserRole> getRoles() {
		return roles;
	}

	public void setRoles(Set<UserRole> roles) {
		this.roles = roles;
	}

//	public User(String userName, String password, boolean isActive)
//	{
//		this.userName=userName;
//		this.password=password;
//		this.isActive=isActive;
//	}
	
//	@Override
//	public int hashCode()
//	{
//		return userId.hashCode();
//	}

	@Override
	public boolean equals(Object obj)
	{
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		return sameIdentityAs(other);
	}

	public boolean sameIdentityAs(User other)
	{
		return other != null && name.equals(other.name);
	}
	
	// How to hide this hibernate specific constructor?
	public User(){}
	
}
